﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using FantastPlatform.Framework.Core;
using System.Reflection;
using System.IO;
using System.Collections;
using NHibernate.Collection;

namespace FantastPlatform.Framework.Common
{
    public static class XMLSerializable
    {
        public static string ToXmlString(object instance)
        {
            if (instance == null)
                throw new ArgumentNullException();

            IItem entity = instance as IItem;
            Type t = instance.GetType();

            XmlDocument xml = GetXml(t);

            foreach (XmlNode node in xml.DocumentElement.SelectNodes("./property"))
            {
                string name = node.Attributes["name"].Value;
                //bool IsCollection = bool.Parse(node.Attributes["IsCollection"].Value);
                string type = node.Attributes["Type"].Value;

                PropertyInfo property = t.GetProperty(name);

                object value = null;

                if (!type.StartsWith("System"))
                {

                    value = property.GetValue(instance, null);

                    if (value is IEnumerable)
                    {
                        if (!(value is PersistentBag))
                            throw new NotImplementedException("Only support type of Bag !");

                        List<string> list = new List<string>();

                        foreach (var obj in value as IEnumerable)
                        {
                            list.Add((obj as IItem).Name);
                        }

                        node.InnerText = string.Join(",", list.ToArray());
                    }
                    else
                    {
                        node.InnerText = value == null ? "" : (value as IItem).Name;
                    }

                }
                else
                {
                    value = property.GetValue(instance, null);
                    node.InnerText = value == null ? "" : value.ToString();
                }
            }

            return xml.InnerXml;
        }

        //public static Object ToObj(string TypeName, string instance)
        //{
        //    object obj = EntityFactory.GetEntity(TypeName);

        //    XmlDocument xml = new XmlDocument();
        //    xml.LoadXml(instance);

        //    foreach (PropertyInfo property in obj.GetType().GetProperties())
        //    {
        //        XmlNode node = xml.DocumentElement.SelectSingleNode(string.Format("./property[@name='{0}']", property.Name));
        //        if (node == null)
        //            continue;

        //        bool IsCollection = bool.Parse(node.Attributes["IsCollection"].Value);
        //        string type = node.Attributes["Type"].Value;
        //        string value = node.InnerText;

        //        if (!type.StartsWith("System"))
        //        {
        //            if (IsCollection)
        //            {
        //                IList<Yaxunsoft.PIS.Model.User.IRole> list = new List<Yaxunsoft.PIS.Model.User.IRole>();
        //                foreach (var i in value.Split(','))
        //                {
        //                    if (string.IsNullOrEmpty(i))
        //                        continue;
        //                    Yaxunsoft.PIS.Model.User.IRole subObj = (Yaxunsoft.PIS.Model.User.IRole)(EntityFactory.GetEntity(type));
        //                    subObj.Id = int.Parse(i);
        //                    list.Add(subObj);
        //                }
        //                property.SetValue(obj, list, null);
        //            }
        //            else
        //            {
        //                IItem subObj = (IItem)(EntityFactory.GetEntity(type));
        //                subObj.Id = int.Parse(value);
        //                property.SetValue(obj, subObj, null);
        //            }
        //        }
        //        else
        //        {
        //            if (!string.IsNullOrEmpty(value))
        //                property.SetValue(obj, Convert.ChangeType(value, Type.GetType(type)), null);
        //        }
        //    }

        //    return obj;
        //}

        public static XmlDocument GetXml(Type t)
        {
            Assembly ass = Assembly.GetAssembly(t);
            Stream stream = ass.GetManifestResourceStream(t.FullName + ".Info.xml");

            XmlDocument xml = new XmlDocument();

            xml.Load(stream);

            return xml;
        }

        public static XmlDocument GetXml(string TypeName)
        {
            Type t = Type.GetType(TypeName);

            return GetXml(t);
        }
    }
}
